package com.android.questions.ui.view;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import androidx.annotation.Nullable;

import com.qq.e.o.utils.DisplayUtil;
import com.qq.e.o.utils.Utils;

import java.util.ArrayList;
import java.util.List;

public class QALuckyView extends View {

    //最中心
    private final RectF mInnerRange = new RectF();
    //中间
    private final RectF mMidRange = new RectF();
    //文字重绘区域
    private final Rect mTextRange = new Rect();
    //各个圆环的宽度比例。
    private final float mInnerWidthScale = 205.0f;//中心圆环
    private final float mBaseWidthScale = 300.0f;//总权重
    //屏幕宽度
    private int mScreenWidth;
    //绘制最里面盘块的画笔
    private Paint mInnerArcPaint;
    //绘制文本的画笔
    private Paint mTextPaint;
    //整个盘块的直径
    private int mRadius;
    //转盘的中心位置
    private int mCenterX;
    private int mCenterY;
    //View padding
    private int mPaddingLeft;
    private int mPaddingTop;
    //初始角度
    private float mStartAngle = 250f;
    //停止指针指向的下标
    private int mStopPosition = 0;
    //旋转时间 ms
    private long mDelayMillis = 5000L;
    //额外转动的圈数
    private int mTurnsNum = 8;
    //默认字体大小
    private float mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
            10, getResources().getDisplayMetrics());
    //item个数
    private int mItemCount = 8;
    //盘块图片
    private Bitmap[] bitmapList = null;
    //盘块文字描述
    private List<String> textList = null;
    //中心盘块的颜色
    private int[] mInnerColor = new int[]{0xFFFFD9A8, 0xFFFFECB2, 0xFFFFF7DD};
    //中间盘块的颜色
//    private final int[] mTextColor = new int[]{0xFF292929, 0xffff1e29};
    //转盘旋转的状态监听器
    private OnRotationListener mListener;
    private ValueAnimator valueAnimator;
    private int defAngle;
    private Bitmap defaultBitmap;

    public QALuckyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        measureScreenSize();
        initData(context);
        initPaint();
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    public QALuckyView(Context context) {
        this(context, null);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        mPaddingLeft = getPaddingLeft();
        int mPaddingRight = getPaddingRight();
        int mPaddingBottom = getPaddingBottom();
        mPaddingTop = getPaddingTop();

        if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(mScreenWidth, mScreenWidth - mPaddingLeft - mPaddingRight);
        } else if (widthSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(heightSpecSize, heightSpecSize);
        } else if (heightSpecMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(widthSpecSize, widthSpecSize);
        }

        //直径
        mRadius = Math.min(getMeasuredWidth() - mPaddingLeft - mPaddingRight, getMeasuredHeight() - mPaddingTop - mPaddingBottom);
        //中心点, 以左上角为准。
        mCenterX = getPaddingLeft() + (int) (mRadius / 2f);
        mCenterY = getPaddingTop() + (int) (mRadius / 2f);
        initRect();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制盘块
        float tmpAngle = mStartAngle;
        float sweepAngle = mItemCount == 0 ? 360 : 360f / mItemCount;

        int mod = 3;
        if (mItemCount % 2 == 0) {
            if (mItemCount % 3 != 0) {
                mod = 2;
            }
        }

        for (int i = 0; i < mItemCount; i++) {
            mInnerArcPaint.setColor(mInnerColor[i % mod]);
//            mTextPaint.setColor(mTextColor[i % 3]);
            //绘制盘块
            canvas.drawArc(mInnerRange, tmpAngle, sweepAngle, true, mInnerArcPaint);
            //绘制文本
            if (textList != null && textList.size() > i && textList.get(i) != null){
                drawText(canvas, tmpAngle, sweepAngle, textList.get(i));

            }
            if (bitmapList != null && bitmapList.length > i && bitmapList[i] != null) {
                drawBitmap(canvas, tmpAngle, bitmapList[i]);
            } else {
                drawBitmap(canvas, tmpAngle, defaultBitmap);
            }
            tmpAngle += sweepAngle;
        }
    }

    //初始化部分数据
    private void initData(Context context) {
        defAngle = 360 - (360 / mItemCount / 2 + 90);
        mStartAngle = defAngle;
        defaultBitmap = BitmapFactory.decodeResource(getResources(), Utils.getDrawableByName(context, "hxc_lucky_box"));
        textList = new ArrayList<>();
        for (int i = 0; i < mItemCount; i++) {
            textList.add("奖品" + (i + 1));
        }
    }

    //初始化画笔
    private void initPaint() {
        //初始化绘制最中心盘块的画笔
        mInnerArcPaint = new Paint();
        mInnerArcPaint.setAntiAlias(true);
        mInnerArcPaint.setDither(true);

        //初始化文字绘制画笔
        mTextPaint = new Paint();
        mTextPaint.setColor(0xff666666);
        mTextPaint.setTextSize(mTextSize);
        mTextPaint.setAntiAlias(true);
        mTextPaint.setDither(true);
    }

    //计算屏幕尺寸
    private void measureScreenSize() {
        DisplayMetrics dm = getResources().getDisplayMetrics();
        mScreenWidth = dm.widthPixels;
    }

    /**
     * 根据控件大小确定绘制范围
     */
    private void initRect() {
        //初始化内部盘块绘制的范围
        mInnerRange.set(mPaddingLeft + (1 - mInnerWidthScale / mBaseWidthScale) * mRadius / 2f
                , mPaddingTop + (1 - mInnerWidthScale / mBaseWidthScale) * mRadius / 2f
                , mPaddingLeft + (1 + mInnerWidthScale / mBaseWidthScale) * mRadius / 2f
                , mPaddingTop + (1 + mInnerWidthScale / mBaseWidthScale) * mRadius / 2f);
        //初始化中间盘块的范围
        mMidRange.set(mPaddingLeft, mPaddingTop, mPaddingLeft + mRadius, mPaddingTop + mRadius);
    }

    /**
     * 绘制每个盘块的文本
     */
    private void drawText(Canvas canvas, float tmpAngle, float sweepAngle, String string) {
        Path path = new Path();
        path.addArc(mInnerRange, tmpAngle, sweepAngle);
        //利用水平偏移量让文字居中
        float textWidth = mTextPaint.measureText(string);
        float hOffset = (float) (mRadius * (mInnerWidthScale / mBaseWidthScale) * Math.PI / mItemCount / 2 - textWidth / 2);
        //按钮权重
        float mBtnWidthScale = 100.0f;
        float vOffset = mRadius / 4f * ((mInnerWidthScale - mBtnWidthScale) / 2) / mBaseWidthScale;//垂直偏移量
        canvas.drawTextOnPath(string, path, hOffset, vOffset, mTextPaint);
    }

    private void drawBitmap(Canvas canvas, float tmpAngle, Bitmap bitmap) {
        // 设置图片的宽度为直径的1/9
        int imgWidth = mRadius / mItemCount;

        int x = mCenterX;
        int y = (mCenterY - ((int) (mRadius / 2f) / 2) + DisplayUtil.dp2px(getContext(), 10));

        // 确定绘制图片的位置
        Rect rect = new Rect(x - imgWidth / 3, y - imgWidth / 3, x + imgWidth / 3, y + imgWidth / 3);
        canvas.save();

        canvas.rotate(tmpAngle - defAngle, mCenterX, mCenterY);
        canvas.drawBitmap(bitmap, null, rect, null);
        canvas.restore();
    }

    /**
     * 开始旋转
     */
    public void startRotation() {
        initAngle();
        initRotationAnimator();
        valueAnimator.start();
    }

    /**
     * 转动多长时间后停止  毫秒
     *
     * @param delayMillis
     */
    public void startRotatingDelay(long delayMillis) {
        this.mDelayMillis = delayMillis;
        startRotation();
    }

    /**
     * 初始化角度
     */
    private void initAngle() {
        mStartAngle = defAngle;
        invalidate();
    }

    private void initRotationAnimator() {
        valueAnimator = ValueAnimator.ofFloat(mStartAngle, 360f * mTurnsNum - (360f / mItemCount) * mStopPosition + mStartAngle);
        //valueAnimator.setInterpolator(new DecelerateInterpolator(1f));
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        //valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setDuration(getDelayMillis());
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mListener != null) {
                    mListener.onStop(mStopPosition);
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //animation.getAnimatedValue()
                mStartAngle = ((float) animation.getAnimatedValue() + 360) % 360;
                invalidate(new Rect((int) mMidRange.left, (int) mMidRange.top, (int) mMidRange.right, (int) mMidRange.bottom));
            }
        });

    }

    public void removeAnimation() {
        if (valueAnimator != null) {
            valueAnimator.removeAllUpdateListeners();
            valueAnimator.removeAllListeners();
        }
    }

    /**
     * 监听转动结束
     *
     * @param listener
     */
    public void setOnRotationListener(OnRotationListener listener) {
        this.mListener = listener;
    }

    /**
     * 设置字体大小  单位：sp
     */
    public void setTextSize(int textSize) {
        mTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                textSize, getResources().getDisplayMetrics());
    }

    /**
     * 设置初始旋转角度
     */
    public void setStartAngle(int startAngle) {
        mStartAngle = startAngle;
    }

    public int getmItemCount() {
        return mItemCount;
    }

    public void setmItemCount(int mItemCount) {
        this.mItemCount = mItemCount;
    }

    public List<String> getTextList() {
        return textList;
    }

    public void setTextList(List<String> textList) {
        defAngle = 360 - (360 / mItemCount / 2 + 90);
        mStartAngle = defAngle;
        this.textList = textList;
//        mItemCount = textList.size();
        mTextRange.set((int) mInnerRange.left, (int) mInnerRange.top, (int) mInnerRange.right, (int) mInnerRange.bottom);
        invalidate(mTextRange);
    }

    public void setData(List<String> textList, List<Bitmap> bitmapList) {
        defAngle = 360 - (360 / mItemCount / 2 + 90);
        mStartAngle = defAngle;
        this.textList = textList;
//        mItemCount = textList.size();
        this.bitmapList = new Bitmap[bitmapList.size()];
        bitmapList.toArray(this.bitmapList);
        mTextRange.set((int) mInnerRange.left, (int) mInnerRange.top, (int) mInnerRange.right, (int) mInnerRange.bottom);
        invalidate(mTextRange);
    }

    public void setBitmapList(List<Bitmap> bitmapList) {
        defAngle = 360 - (360 / mItemCount / 2 + 90);
        mStartAngle = defAngle;
        this.bitmapList = new Bitmap[bitmapList.size()];
        bitmapList.toArray(this.bitmapList);
        mTextRange.set((int) mInnerRange.left, (int) mInnerRange.top, (int) mInnerRange.right, (int) mInnerRange.bottom);
        invalidate(mTextRange);
    }

    /**
     * 设置最内部盘块颜色
     *
     * @param colorList
     */
    public void setInnerColor(int[] colorList) {
        this.mInnerColor = colorList;
    }

    /**
     * 获取停止指针指向转盘的下标
     */
    private int getStopPosition() {
        return mStopPosition;
    }

    /**
     * 设置停止指针指向转盘的下标
     */
    public void setStopPosition(int stopPosition) {
        if (stopPosition >= mItemCount) {
            throw new IllegalArgumentException("stopPosition不能大于盘块item个数");
        }
        this.mStopPosition = stopPosition;
    }

    /**
     * 获取转动时间
     */
    private Long getDelayMillis() {
        return this.mDelayMillis;
    }

    /**
     * 设置转动时间
     *
     * @param delayMillis
     */
    private void setDelayMillis(long delayMillis) {
        this.mDelayMillis = delayMillis;
    }

    /**
     * 获取转的圈数
     *
     * @return
     */
    public int getTurnsNum() {
        return mTurnsNum;
    }

    /**
     * 设置转到的圈数
     *
     * @param turnsNum
     */
    public void setTurnsNum(int turnsNum) {
        this.mTurnsNum = turnsNum;
    }

    /**
     * 转盘旋转状态监听器
     */
    public interface OnRotationListener {
        void onStop(int currentItem);//动画结束
    }

}
